﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using Models;
using IP2Region;
using Microsoft.AspNetCore.Http;

namespace Common
{
  public static class Util
  {
    public static string GetAddressByIP(string ip)
    {
      try
      {
        using (var search = new DbSearcher(Environment.CurrentDirectory + @"\ip2region.db"))
        {
          var a = search.BinarySearch(ip);
          var arr = a.Region.Split('|');
          var addr = "";
          foreach (var item in arr)
          {
            if (item == "0") continue;
            if (item == "中国") continue;
            addr += item;
          }
          return addr;
        }
      }
      catch (Exception)
      {
        return string.Empty;
      }
    }

    public static string RestoreInfo(string qrinfo)
    {
      int key;
      try
      {
        key = Convert.ToInt32(qrinfo.Substring(qrinfo.Length - 3)) - 256;
        string values = qrinfo.Substring(0, qrinfo.Length - 3);
        values = reverse(values);
        return UnicodeToString(StringToUnicode(values, key));
      }
      catch (Exception)
      {
        return null;
      }
    }

    private static string UnicodeToString(string str)
    {
      string outStr = "";
      if (!string.IsNullOrEmpty(str))
      {
        string[] strlist = str.Replace("\\", "").Split('u');
        for (int i = 1; i < strlist.Length; i++)
        {
          //将unicode字符转为10进制整数，然后转为char中文字符  
          outStr += (char)int.Parse(strlist[i], NumberStyles.HexNumber);
        }
      }
      return outStr;
    }

    private static string StringToUnicode(string str, int offset)
    {
      StringBuilder sb = new StringBuilder();
      for (int i = 0; i + 4 <= str.Length; i = i + 4)
      {
        string ss = str.Substring(i, 4);
        int intcode = Convert.ToInt32(ss, 16);
        if (intcode != 65535)
        {
          int unicode = intcode - offset;
          string tmp = "\\u" + unicode.ToString("X4");
          sb.Append(tmp);
        }
      }
      return sb.ToString();
    }

    private static string reverse(string str)
    {
      return new string(str.ToCharArray().Reverse().ToArray());
    }

    /// <summary>
    ///     获取内置接口
    /// </summary>
    /// <returns></returns>
    public static Type[] GetPluginList<T>(string filter)
    {
      List<Type> list = new List<Type>();
      var types = typeof(T).Assembly.GetTypes().Where(t => t.BaseType == typeof(T)).ToArray();
      var typesExt = GetExtPluginList<T>(filter);
      list.AddRange(types);
      list.AddRange(typesExt);
      return list.ToArray();
    }

    /// <summary>
    ///     获取外置接口
    /// </summary>
    /// <returns></returns>
    public static List<Type> GetExtPluginList<T>(string filter)
    {
      var dlls = Directory.GetFiles(AssemblyDirectory, filter);
      List<Type> list = new List<Type>();
      foreach (var dll in dlls)
      {
        Assembly assembly = Assembly.LoadFile(dll);
        Type[] types = assembly.GetTypes().Where(t => t.BaseType == typeof(T)).ToArray();
        list.AddRange(types);
      }
      return list;
    }

    /// <summary>
    ///     程序集所在目录
    /// </summary>
    public static string AssemblyDirectory
    {
      get
      {
        string codeBase = Assembly.GetExecutingAssembly().Location;
        UriBuilder uri = new UriBuilder(codeBase);
        string path = Uri.UnescapeDataString(uri.Path);
        return Path.GetDirectoryName(path);
      }
    }
  }
}
